package com.atguigu.springcloud.service.impl;

import com.atguigu.springcloud.config.RabbitMQConst;
import com.atguigu.springcloud.config.Result;
import com.atguigu.springcloud.entity.MovieInfo;
import com.atguigu.springcloud.entity.MovieTicketInfo;
import com.atguigu.springcloud.mapper.MoiveTicketInfoMapper;
import com.atguigu.springcloud.service.IMoiveTikectService;
import com.atguigu.springcloud.utils.BeanMapUtilByIntros;
import com.atguigu.springcloud.utils.MovieFeignService;
import com.atguigu.springcloud.utils.RedisUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Random;

/**
 * @Author zhenyu
 * @desc
 * @Date 2022/10/14 11:36
 * @Version 1.0
 */
@Slf4j
@Primary
@Service
public class IMovieTikectServiceImpl extends ServiceImpl<MoiveTicketInfoMapper, MovieTicketInfo> implements IMoiveTikectService {

  @Autowired
  private MovieFeignService movieFeignService;

  @Autowired
  private RabbitTemplate rabbitTemplate;

  @Autowired
  private RedisUtil redisUtil;

  /**
   * 购票
   * @param number 票数
   * @param movieId 电影ID
   * @param userId 购买人ID
   * @return
   */
  @Override
  @Transactional(rollbackFor = RuntimeException.class)
  public Result<String> bugTicket(Integer number, Integer movieId, Integer userId) throws IllegalAccessException {

    if(userId == null){
      userId = 1000;
    }

    //获取购买电影的详情信息
    MovieInfo moiveDetail = movieFeignService.getMoiveDetail(movieId);

    //判断上线状态（状态：0未上线， 1已上线）
    if(moiveDetail.getState() == 0){
      return Result.fail("电影暂未上线");
    }

    //判断可卖票数是否大于 0和大于等于当前购买票数
    if(moiveDetail.getTicketNumber() == 0 || (number > moiveDetail.getTicketNumber())){
      return Result.fail("剩余票数不足，仅剩：" + moiveDetail.getTicketNumber() + " 张");
    }

    //生成取票码
    int ticketCode = new Random().nextInt(9000) + 1000;
    log.info("取票码为：" + ticketCode);

    //保存购票记录（在消费者完成）
    insert(number, movieId, userId, moiveDetail, String.valueOf(ticketCode));

    //更新Redis缓存电影余票
    updateMovieOfRedis(number, movieId, moiveDetail);

    //更新MySQL余票张数（在消费者完成）
//    movieFeignService.updateMovieNum(movieId,number);

    return Result.success("取票码为：" + ticketCode);
  }

  private void updateMovieOfRedis(Integer number, Integer movieId, MovieInfo moiveDetail) throws IllegalAccessException {

    log.info("电影Redis缓存信息开始更新...");

    if(redisUtil.hasKey(String.valueOf(movieId))){
      MovieInfo movieInfo = new MovieInfo();
      movieInfo.setId(movieId);
      movieInfo.setName(moiveDetail.getName());
      movieInfo.setOfflineDate(moiveDetail.getOfflineDate());
      movieInfo.setOnlineDate(moiveDetail.getOnlineDate());
      movieInfo.setPrice(moiveDetail.getPrice());
      movieInfo.setState(moiveDetail.getState());
      movieInfo.setTicketNumber(moiveDetail.getTicketNumber() - number);
      redisUtil.hmset(String.valueOf(movieId), BeanMapUtilByIntros.beanToMap(movieInfo));
    }

    log.info("电影Redis缓存信息更新完成...");
  }

  private void insert(Integer number, Integer movieId, @Value("${user.id}") Integer userId, MovieInfo moiveDetail, String ticketCode) {
    BigDecimal payAmount = BigDecimal.ZERO;

    //电影票单价
    BigDecimal price = moiveDetail.getPrice();
    BigDecimal numberToBigDecimal = new BigDecimal(number);
    payAmount = price.multiply(numberToBigDecimal);

    MovieTicketInfo movieTicketInfo = new MovieTicketInfo();
    movieTicketInfo.setMovieId(movieId);
    movieTicketInfo.setNumber(number);
    movieTicketInfo.setPayAmount(payAmount);
    movieTicketInfo.setUserId(userId);
    movieTicketInfo.setTicketCode(ticketCode);

    //推送购票信息到RabbitMQ(消费者入库)
    rabbitTemplate.convertAndSend(RabbitMQConst.MOVIE_TICKET_EXCHANGE, RabbitMQConst.MOVIE_TICKET_ROUTINGKEY, movieTicketInfo);

    //插入数据库
//    this.baseMapper.insert(movieTicketInfo);
  }
}
